package ltd.cheers.mall.service.impl;

import ltd.cheers.mall.common.*;
import ltd.cheers.mall.controller.vo.*;
import ltd.cheers.mall.dao.CheersMallGoodsMapper;
import ltd.cheers.mall.dao.CheersMallOrderItemMapper;
import ltd.cheers.mall.dao.CheersMallOrderMapper;
import ltd.cheers.mall.dao.CheersMallShoppingCartItemMapper;
import ltd.cheers.mall.entity.CheersMallGoods;
import ltd.cheers.mall.entity.CheersMallOrder;
import ltd.cheers.mall.entity.CheersMallOrderItem;
import ltd.cheers.mall.entity.StockNumDTO;
import ltd.cheers.mall.service.CheersMallOrderService;
import ltd.cheers.mall.util.BeanUtil;
import ltd.cheers.mall.util.NumberUtil;
import ltd.cheers.mall.util.PageQueryUtil;
import ltd.cheers.mall.util.PageResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * @author: LiHuanYang
 * @date: 2020/3/25 下午 11:44
 */

@Service
public class CheersMallOrderServiceImpl implements CheersMallOrderService {

    @Resource
    private CheersMallOrderMapper cheersMallOrderMapper;
    @Resource
    private CheersMallOrderItemMapper cheersMallOrderItemMapper;
    @Resource
    private CheersMallShoppingCartItemMapper cheersMallShoppingCartItemMapper;
    @Resource
    private CheersMallGoodsMapper cheersMallGoodsMapper;

    @Override
    public PageResult getCheersMallOrdersPage(PageQueryUtil pageUtil) {
        List<CheersMallOrder> cheersMallOrders = cheersMallOrderMapper.findCheersMallOrderList(pageUtil);
        int total = cheersMallOrderMapper.getTotalCheersMallOrders(pageUtil);
        PageResult pageResult = new PageResult(cheersMallOrders, total, pageUtil.getLimit(), pageUtil.getPage());
        return pageResult;
    }

    @Override
    @Transactional
    public String updateOrderInfo(CheersMallOrder cheersMallOrder) {
        CheersMallOrder temp = cheersMallOrderMapper.selectByPrimaryKey(cheersMallOrder.getOrderId());
        //不为空且orderStatus>=0且状态为出库之前可以修改部分信息
        if (temp != null && temp.getOrderStatus() >= 0 && temp.getOrderStatus() < 3) {
            temp.setTotalPrice(cheersMallOrder.getTotalPrice());
            temp.setUserName(cheersMallOrder.getUserName());
            temp.setUserPhone(cheersMallOrder.getUserPhone());
            temp.setUserAddress(cheersMallOrder.getUserAddress());
            temp.setUserAddress(cheersMallOrder.getUserAddress());
            temp.setUpdateTime(new Date());
            if (cheersMallOrderMapper.updateByPrimaryKeySelective(temp) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            }
            return ServiceResultEnum.DB_ERROR.getResult();
        }
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String checkDone(Long[] ids) {
        //查询所有的订单 判断状态 修改状态和更新时间
        List<CheersMallOrder> orders = cheersMallOrderMapper.selectByPrimaryKeys(Arrays.asList(ids));
        String errorOrderNos = "";
        if (!CollectionUtils.isEmpty(orders)) {
            for (CheersMallOrder cheersMallOrder : orders) {
                if (cheersMallOrder.getIsDeleted() == 1) {
                    errorOrderNos += cheersMallOrder.getOrderNo() + " ";
                    continue;
                }
                if (cheersMallOrder.getOrderStatus() != 1) {
                    errorOrderNos += cheersMallOrder.getOrderNo() + " ";
                }
            }
            if (StringUtils.isEmpty(errorOrderNos)) {
                //订单状态正常 可以执行配货完成操作 修改订单状态和更新时间
                if (cheersMallOrderMapper.checkDone(Arrays.asList(ids)) > 0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }
            } else {
                //订单此时不可执行出库操作
                if (errorOrderNos.length() > 0 && errorOrderNos.length() < 100) {
                    return errorOrderNos + "订单的状态不是支付成功无法执行出库操作";
                } else {
                    return "你选择了太多状态不是支付成功的订单，无法执行配货完成操作";
                }
            }
        }
        //未查询到数据 返回错误提示
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String checkOut(Long[] ids) {
        //查询所有的订单 判断状态 修改状态和更新时间
        List<CheersMallOrder> orders = cheersMallOrderMapper.selectByPrimaryKeys(Arrays.asList(ids));
        String errorOrderNos = "";
        if (!CollectionUtils.isEmpty(orders)) {
            for (CheersMallOrder cheersMallOrder : orders) {
                // isDeleted=1 一定为已关闭订单
                if (cheersMallOrder.getIsDeleted() == 1) {
                    errorOrderNos += cheersMallOrder.getOrderNo() + " ";
                    continue;
                }
               // if (cheersMallOrder.getOrderStatus() != 1 && cheersMallOrder.getOrderStatus() != 2) {
                if (cheersMallOrder.getOrderStatus() != 2) {
                    errorOrderNos += cheersMallOrder.getOrderNo() + " ";
                }
            }
            if (StringUtils.isEmpty(errorOrderNos)) {
                //订单状态正常 可以执行出库操作 修改订单状态和更新时间
                if (cheersMallOrderMapper.checkOut(Arrays.asList(ids)) > 0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }
            } else {
                //订单此时不可执行出库操作
                if (errorOrderNos.length() > 0 && errorOrderNos.length() < 100) {
                    //  return errorOrderNos + "订单的状态不是支付成功或配货完成无法执行出库操作";
                    return errorOrderNos + "订单的状态不是配货完成无法执行出库操作";
                } else {
                    //  return "你选择了太多状态不是支付成功或配货完成的订单，无法执行出库操作";
                    return "你选择了太多状态不是配货完成的订单，无法执行出库操作";
                }
            }
        }
        //未查询到数据 返回错误提示
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String closeOrder(Long[] ids) {
        //查询所有的订单 判断状态 修改状态和更新时间
        List<CheersMallOrder> orders = cheersMallOrderMapper.selectByPrimaryKeys(Arrays.asList(ids));
        String errorOrderNos = "";
        if (!CollectionUtils.isEmpty(orders)) {
            for (CheersMallOrder cheersMallOrder : orders) {
                // isDeleted=1 一定为已关闭订单
                if (cheersMallOrder.getIsDeleted() == 1) {
                    errorOrderNos += cheersMallOrder.getOrderNo() + " ";
                    continue;
                }
                //已关闭或者已完成无法关闭订单
                if (cheersMallOrder.getOrderStatus() == 4 || cheersMallOrder.getOrderStatus() < 0) {
                    errorOrderNos += cheersMallOrder.getOrderNo() + " ";
                }
            }
            if (StringUtils.isEmpty(errorOrderNos)) {
                //订单状态正常 可以执行关闭操作 修改订单状态和更新时间
                if (cheersMallOrderMapper.closeOrder(Arrays.asList(ids), CheersMallOrderStatusEnum.ORDER_CLOSED_BY_JUDGE.getOrderStatus()) > 0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }
            } else {
                //订单此时不可执行关闭操作
                if (errorOrderNos.length() > 0 && errorOrderNos.length() < 100) {
                    return errorOrderNos + "订单不能执行关闭操作";
                } else {
                    return "你选择的订单不能执行关闭操作";
                }
            }
        }
        //未查询到数据 返回错误提示
        return ServiceResultEnum.DATA_NOT_EXIST.getResult();
    }

    @Override
    @Transactional
    public String saveOrder(CheersMallUserVO user, List<CheersMallShoppingCartItemVO> myShoppingCartItems) {
        List<Long> itemIdList = myShoppingCartItems.stream().map(CheersMallShoppingCartItemVO::getCartItemId).collect(Collectors.toList());
        List<Long> goodsIds = myShoppingCartItems.stream().map(CheersMallShoppingCartItemVO::getGoodsId).collect(Collectors.toList());
        List<CheersMallGoods> cheersMallGoods = cheersMallGoodsMapper.selectByPrimaryKeys(goodsIds);
        Map<Long, CheersMallGoods> cheersMallGoodsMap = cheersMallGoods.stream().collect(Collectors.toMap(CheersMallGoods::getGoodsId, Function.identity(), (entity1, entity2) -> entity1));
        //判断商品库存
        for (CheersMallShoppingCartItemVO shoppingCartItemVO : myShoppingCartItems) {
            //查出的商品中不存在购物车中的这条关联商品数据，直接返回错误提醒
            if (!cheersMallGoodsMap.containsKey(shoppingCartItemVO.getGoodsId())) {
                CheersMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
            }
            //存在数量大于库存的情况，直接返回错误提醒
            if (shoppingCartItemVO.getGoodsCount() > cheersMallGoodsMap.get(shoppingCartItemVO.getGoodsId()).getStockNum()) {
                CheersMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
            }
        }
        //删除购物项
        if (!CollectionUtils.isEmpty(itemIdList) && !CollectionUtils.isEmpty(goodsIds) && !CollectionUtils.isEmpty(cheersMallGoods)) {
            if (cheersMallShoppingCartItemMapper.deleteBatch(itemIdList) > 0) {
                List<StockNumDTO> stockNumDTOS = BeanUtil.copyList(myShoppingCartItems, StockNumDTO.class);
                int updateStockNumResult = cheersMallGoodsMapper.updateStockNum(stockNumDTOS);
                if (updateStockNumResult < 1) {
                    CheersMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
                }
                //生成订单号
                String orderNo = NumberUtil.genOrderNo();
                int priceTotal = 0;
                //保存订单
                CheersMallOrder cheersMallOrder = new CheersMallOrder();
                cheersMallOrder.setOrderNo(orderNo);
                cheersMallOrder.setUserId(user.getUserId());
                cheersMallOrder.setUserAddress(user.getAddress());
                //总价
                for (CheersMallShoppingCartItemVO cheersMallShoppingCartItemVO : myShoppingCartItems) {
                    priceTotal += cheersMallShoppingCartItemVO.getGoodsCount() * cheersMallShoppingCartItemVO.getSellingPrice();
                }
                if (priceTotal < 1) {
                    CheersMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                cheersMallOrder.setTotalPrice(priceTotal);
                //todo 订单body字段，用来作为生成支付单描述信息，暂时未接入第三方支付接口，故该字段暂时设为空字符串
                String extraInfo = "";
                cheersMallOrder.setExtraInfo(extraInfo);
                //生成订单项并保存订单项纪录
                if (cheersMallOrderMapper.insertSelective(cheersMallOrder) > 0) {
                    //生成所有的订单项快照，并保存至数据库
                    List<CheersMallOrderItem> cheersMallOrderItems = new ArrayList<>();
                    for (CheersMallShoppingCartItemVO cheersMallShoppingCartItemVO : myShoppingCartItems) {
                        CheersMallOrderItem cheersMallOrderItem = new CheersMallOrderItem();
                        //使用BeanUtil工具类将cheersMallShoppingCartItemVO中的属性复制到cheersMallOrderItem对象中
                        BeanUtil.copyProperties(cheersMallShoppingCartItemVO, cheersMallOrderItem);
                        //CheersMallOrderMapper文件insert()方法中使用了useGeneratedKeys因此orderId可以获取到
                        cheersMallOrderItem.setOrderId(cheersMallOrder.getOrderId());
                        cheersMallOrderItems.add(cheersMallOrderItem);
                    }
                    //保存至数据库
                    if (cheersMallOrderItemMapper.insertBatch(cheersMallOrderItems) > 0) {
                        //所有操作成功后，将订单号返回，以供Controller方法跳转到订单详情
                        return orderNo;
                    }
                    CheersMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                CheersMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
            }
            CheersMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
        }
        CheersMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
        return ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult();
    }

    @Override
    public CheersMallOrderDetailVO getOrderDetailByOrderNo(String orderNo, Long userId) {
        CheersMallOrder cheersMallOrder = cheersMallOrderMapper.selectByOrderNo(orderNo);
        if (cheersMallOrder != null) {
            //todo 验证是否是当前userId下的订单，否则报错
            List<CheersMallOrderItem> orderItems = cheersMallOrderItemMapper.selectByOrderId(cheersMallOrder.getOrderId());
            //获取订单项数据
            if (!CollectionUtils.isEmpty(orderItems)) {
                List<CheersMallOrderItemVO> cheersMallOrderItemVOS = BeanUtil.copyList(orderItems, CheersMallOrderItemVO.class);
                CheersMallOrderDetailVO cheersMallOrderDetailVO = new CheersMallOrderDetailVO();
                BeanUtil.copyProperties(cheersMallOrder, cheersMallOrderDetailVO);
                cheersMallOrderDetailVO.setOrderStatusString(CheersMallOrderStatusEnum.getCheersMallOrderStatusEnumByStatus(cheersMallOrderDetailVO.getOrderStatus()).getName());
                cheersMallOrderDetailVO.setPayTypeString(PayTypeEnum.getPayTypeEnumByType(cheersMallOrderDetailVO.getPayType()).getName());
                cheersMallOrderDetailVO.setCheersMallOrderItemVOS(cheersMallOrderItemVOS);
                return cheersMallOrderDetailVO;
            }
        }
        return null;
    }

    @Override
    public CheersMallOrder getCheersMallOrderByOrderNo(String orderNo) {
        return cheersMallOrderMapper.selectByOrderNo(orderNo);
    }

    @Override
    public PageResult getMyOrders(PageQueryUtil pageUtil) {
        int total = cheersMallOrderMapper.getTotalCheersMallOrders(pageUtil);
        List<CheersMallOrder> cheersMallOrders = cheersMallOrderMapper.findCheersMallOrderList(pageUtil);
        List<CheersMallOrderListVO> orderListVOS = new ArrayList<>();
        if (total > 0) {
            //数据转换 将实体类转成vo
            orderListVOS = BeanUtil.copyList(cheersMallOrders, CheersMallOrderListVO.class);
            //设置订单状态中文显示值
            for (CheersMallOrderListVO cheersMallOrderListVO : orderListVOS) {
                cheersMallOrderListVO.setOrderStatusString(CheersMallOrderStatusEnum.getCheersMallOrderStatusEnumByStatus(cheersMallOrderListVO.getOrderStatus()).getName());
            }
            List<Long> orderIds = cheersMallOrders.stream().map(CheersMallOrder::getOrderId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(orderIds)) {
                List<CheersMallOrderItem> orderItems = cheersMallOrderItemMapper.selectByOrderIds(orderIds);
                Map<Long, List<CheersMallOrderItem>> itemByOrderIdMap = orderItems.stream().collect(groupingBy(CheersMallOrderItem::getOrderId));
                for (CheersMallOrderListVO cheersMallOrderListVO : orderListVOS) {
                    //封装每个订单列表对象的订单项数据
                    if (itemByOrderIdMap.containsKey(cheersMallOrderListVO.getOrderId())) {
                        List<CheersMallOrderItem> orderItemListTemp = itemByOrderIdMap.get(cheersMallOrderListVO.getOrderId());
                        //将CheersMallOrderItem对象列表转换成CheersMallOrderItemVO对象列表
                        List<CheersMallOrderItemVO> cheersMallOrderItemVOS = BeanUtil.copyList(orderItemListTemp, CheersMallOrderItemVO.class);
                        cheersMallOrderListVO.setCheersMallOrderItemVOS(cheersMallOrderItemVOS);
                    }
                }
            }
        }
        PageResult pageResult = new PageResult(orderListVOS, total, pageUtil.getLimit(), pageUtil.getPage());
        return pageResult;
    }

    @Override
    public String cancelOrder(String orderNo, Long userId) {
        CheersMallOrder cheersMallOrder = cheersMallOrderMapper.selectByOrderNo(orderNo);
        if (cheersMallOrder != null) {
            //todo 验证是否是当前userId下的订单，否则报错
            //todo 订单状态判断
            if (cheersMallOrderMapper.closeOrder(Collections.singletonList(cheersMallOrder.getOrderId()), CheersMallOrderStatusEnum.ORDER_CLOSED_BY_MALLUSER.getOrderStatus()) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

    @Override
    public String finishOrder(String orderNo, Long userId) {
        CheersMallOrder cheersMallOrder = cheersMallOrderMapper.selectByOrderNo(orderNo);
        if (cheersMallOrder != null) {
            //todo 验证是否是当前userId下的订单，否则报错
            //todo 订单状态判断
            cheersMallOrder.setOrderStatus((byte) CheersMallOrderStatusEnum.ORDER_SUCCESS.getOrderStatus());
            cheersMallOrder.setUpdateTime(new Date());
            if (cheersMallOrderMapper.updateByPrimaryKeySelective(cheersMallOrder) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

    @Override
    public String paySuccess(String orderNo, int payType) {
        CheersMallOrder cheersMallOrder = cheersMallOrderMapper.selectByOrderNo(orderNo);
        if (cheersMallOrder != null) {
            //todo 订单状态判断 非待支付状态下不进行修改操作
            cheersMallOrder.setOrderStatus((byte) CheersMallOrderStatusEnum.OREDER_PAID.getOrderStatus());
            cheersMallOrder.setPayType((byte) payType);
            cheersMallOrder.setPayStatus((byte) PayStatusEnum.PAY_SUCCESS.getPayStatus());
            cheersMallOrder.setPayTime(new Date());
            cheersMallOrder.setUpdateTime(new Date());
            if (cheersMallOrderMapper.updateByPrimaryKeySelective(cheersMallOrder) > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

    @Override
    public List<CheersMallOrderItemVO> getOrderItems(Long id) {
        CheersMallOrder cheersMallOrder = cheersMallOrderMapper.selectByPrimaryKey(id);
        if (cheersMallOrder != null) {
            List<CheersMallOrderItem> orderItems = cheersMallOrderItemMapper.selectByOrderId(cheersMallOrder.getOrderId());
            //获取订单项数据
            if (!CollectionUtils.isEmpty(orderItems)) {
                List<CheersMallOrderItemVO> cheersMallOrderItemVOS = BeanUtil.copyList(orderItems, CheersMallOrderItemVO.class);
                return cheersMallOrderItemVOS;
            }
        }
        return null;
    }

    @Override
    public List<CheersMallOrder> getCheersMallOrderByUserId(String userId) {
        List<CheersMallOrder> cheersMallOrders = cheersMallOrderMapper.selectByUserId(userId);
        if (cheersMallOrders != null){
            //获取订单数据
            //数据转换 将实体类转成vo
            List<CheersMallOrder> orderListS = new ArrayList<>();
            orderListS = BeanUtil.copyList(cheersMallOrders, CheersMallOrder.class);
            return orderListS;
        }
        return null;
    }

    @Override
    public List<CheersMallOrder> getCheersMallFinishOrderByUserId(String userId) {
        List<CheersMallOrder> cheersMallOrders = cheersMallOrderMapper.selectFinishOrdersByUserId(userId);
        if (cheersMallOrders != null){
            //获取订单数据
            //数据转换 将实体类转成vo
            List<CheersMallOrder> orderListS = new ArrayList<>();
            orderListS = BeanUtil.copyList(cheersMallOrders, CheersMallOrder.class);
            return orderListS;
        }
        return null;
    }

    @Override
    public List<CheersMallOrder> getCheersMallOrderByOrderStatus(int orderStatus) {
        List<CheersMallOrder> cheersMallOrders = cheersMallOrderMapper.selectOrdersByOrderStatus(orderStatus);
        if (cheersMallOrders != null){
            //获取订单数据
            //数据转换 将实体类转成vo
            List<CheersMallOrder> orderListS = new ArrayList<>();
            orderListS = BeanUtil.copyList(cheersMallOrders, CheersMallOrder.class);
            return orderListS;
        }
        return null;
    }


}
